package com4280;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashSet;

/**
 * The is the main class for controlling the indexing and search part of the program,
 * it delegates the indexing part to a seperate class and undertakes searches on the completed 
 * index.
 * 
 * @author Mitchell Whitehouse
 * @author Andrew Evans	
 * @author Duncan Grant
 * @version     1                                 
 * @since       1.6                                      
 */
public class MADSearch extends SearchEngine implements SearchEngineInterface{
	

	/**
	 * Class constructor
	 * 
	 */
	public MADSearch(){
			
		openUserInterface();
		
		if (!dirs.exists()) {
            dirs.mkdirs();
        }		
	}

	/**
	 * Method for the GUI to have access to the filename
	 * 
	 * @return String the input file name
	 */
	public String getInputFileName()
	{
		return INPUT_FILENAME;
	}
	/**
	 * Method for the GUI to have access to the filename
	 * 
	 * @return String the output file name
	 */
	
	public String getOutputFileName()
	{
		return OUTPUT_FILENAME;
	}

	/**
	 * Method that creates the final index file from a list of URL's outputted from the 
	 * spider
	 * 
	 * @param inputFileName Name of the file containing indexed URL's
	 * @param outputFileName name of desination file for completed idex file
	 */
	public void IndexCrawledPages(String inputFileName, String outputFileName)
	{	
		// New thread so user interface is still active
		new Thread(new MADIndexer(gui)).start();
		System.out.println("Help!");
		
	}
	
	/**
	 * Method closes the user interface while not terminating MADSearch class
	 */
	public void closeUserInterface() 
	{
		gui.dispose();

	}

	/**
	 * Method loads an index from a file for use in the program
	 * 
	 * Loads a index that is in the correct form in to a 
	 * HashMap<String,ArrayList<String>> containing the term as a key, followed by a
	 * list of URL's that contain this term, for use in the program
	 * 
	 * @param fileName The name of the file containing the index
	 * @return String[] containing the index in string form
	 */
	public String[] loadIndexTable(String fileName)
	{
		ArrayList<String> lines = new ArrayList<String>();
		
		try
		{
			URLs = new ArrayList<String>();
			FileInputStream fstream = new FileInputStream(fileName);
			DataInputStream in = new DataInputStream(fstream);
			BufferedReader br = new BufferedReader(new InputStreamReader(in));
			String strLine;
			//Read File Line By Line
			while ((strLine = br.readLine()) != null)  
			{
				String[] indexTerms = strLine.split(" ");
				ArrayList<String> indexURLs = new ArrayList<String>();
				for(int x = 1; x < indexTerms.length; x++)
				{
					URLs.add(indexTerms[x]);
					indexURLs.add(indexTerms[x]);
				}
				index.put(indexTerms[0],indexURLs);
				lines.add(strLine.trim());
			}
			//Close the input stream
			in.close();
		}
		catch (Exception e){//Catch exception if any
			System.err.println("Error: " + e.getMessage());
		}
		String sLines[] = (String []) lines.toArray (new String [lines.size ()]);
		return sLines;
	}

	/**
	 * Opens the user interface
	 */
	public void openUserInterface() 
	{
		// TODO Auto-generated method stub
		gui = new SearchGUI(this);
	}
	
	/**
	 * Method to search the index, either a pre-loaded one or newly created
	 * 
	 * This method either loads an existing index from file if one has not been
	 * chosen by the user. The method processes the query to remove punctuation, and convert to lower case, to
	 * improve accuracy as this is the from the index terms are in. The method implements
	 * boolean search of single or multiple query terms using the conjunction operator. 
	 * Because of this the results are not ranked.
	 * 
	 * @return String array containing returned URLs from search
	 */
	public String[] search(String keyword)
	{
		if(index.isEmpty()){ //index created
			loadIndexTable(OUTPUT_FILENAME);
		}
		String[] terms = keyword.trim().split(" ");
		HashSet<String> urlSet = new HashSet<String>(URLs);
		for(int x = 0; x < terms.length ; x++)
		{
			if(index.containsKey(terms[x]))
			{
				urlSet.retainAll(index.get(terms[x]));
			}
			else
			{
				urlSet.clear();
			}
		}
		String results [] = (String []) urlSet.toArray (new String [urlSet.size ()]);
		return results;
	}

	public static void main(String[] args)
	{
		MADSearch md = new MADSearch();
	}
 
}
